#pragma once

#include <QHash>
#include <QString>

auto constexpr PLATFORM_LINUX = "linux";
auto constexpr PLATFORM_WINDOWS = "windows";

#if defined(_WIN32)
auto constexpr PLATFORM_CURRENT = "windows";
#elif defined(linux)
auto constexpr PLATFORM_CURRENT = "linux";
#elif defined(__APPLE__)
auto constexpr PLATFORM_CURRENT = "osx";
#endif

struct ExecutableInfo {
    QString name;
    QString runDirectory;
    QHash<QString, QString> executables;

    bool operator==(const ExecutableInfo &other) const;
};

struct TaskInfo {
    QString name;
    QHash<QString, QStringList> commands; // key: platform, value: list of commands
    QString runDirectory;
    bool isBuild = false;

    bool operator==(const TaskInfo &other) const;
};

enum class ProjectType { cmake, cargo, golang, meson, unknown };

struct ProjectBuildConfig {
    ProjectBuildConfig() = default;
    QString sourceDir;
    QString buildDir;
    QList<ExecutableInfo> executables;
    QList<TaskInfo> tasksInfo;

    QString activeExecutableName;
    QString activeTaskName;
    QString displayFilter;
    QString hideFilter;

    // meta data
    bool autoGenerated = true;
    ProjectType projectType = ProjectType::unknown;
    QString name;
    QString fileName;

    static auto tryGuessFromCMake(const QString &directory) -> std::shared_ptr<ProjectBuildConfig>;
    static auto tryGuessFromCargo(const QString &directory) -> std::shared_ptr<ProjectBuildConfig>;
    static auto tryGuessFromGo(const QString &directory) -> std::shared_ptr<ProjectBuildConfig>;
    static auto tryGuessFromMeson(const QString &directory) -> std::shared_ptr<ProjectBuildConfig>;
    static auto buildFromDirectory(const QString &directory) -> std::shared_ptr<ProjectBuildConfig>;
    static auto buildFromFile(const QString &jsonFileName) -> std::shared_ptr<ProjectBuildConfig>;
    static auto canLoadFile(const QString &filename) -> bool;

    auto updateBinaries() -> void;
    auto updateBinariesCMake() -> void;
    auto updateBinariesCargo() -> void;
    auto updateBinariesGo() -> void;
    auto updateBinariesMeson() -> void;

    auto saveToFile(const QString &jsonFileName) -> void;
    auto findIndexOfTask(const QString &taskName) -> int;
    auto findIndexOfExecutable(const QString &executableName) -> int;
    auto getConfigDictionary() const -> const QHash<QString, QString>;
    auto expand(const QString &var) -> QString;

    bool operator==(const ProjectBuildConfig &other) const;
};
